#if _MSC_VER
 #pragma once
#endif // _MSC_VER

#ifndef __HERZELEID_CORERENDERER3_INCLUDED__
 #define __HERZELEID_CORERENDERER3_INCLUDED__
 #include "HerzeleidIRenderer.hxx"

 #ifdef HERZELEID_DESKTOP // Desktop
  #define internal public // For compability
  #define ref // For compability
 #else // Metro Or Phone
 #endif // HERZELEID_DESKTOP

HerzeleidRendererCoreNamespaceBegin ref class CoreRenderer3 : public IRenderer<Device3, Context3>
{
	// Prevent copying 

 #ifdef HERZELEID_DESKTOP // Desktop
	CoreRenderer3(CoreRenderer3 const &);
	CoreRenderer3& operator= (CoreRenderer3 const &);
 #endif // HERZELEID_DESKTOP

	// Internal types 

	typedef HerzeleidRendererResourcesNamespaceImpl::SwapChain SwapChain; 
	typedef std::lock_guard<std::mutex> LockGuard;
	typedef std::mutex Mutex;
	TinyTypeDecl(SwapChain);
	TinyTypeDecl(Mutex);

 #ifdef HERZELEID_DESKTOP // Desktop
protected:
#else
protected private:
 #endif // HERZELEID_DESKTOP

	// Members

	WRL::ComPtr<ImmediateContext3> m_ImmediateContext3; // D3D11 Device Context
	WRL::ComPtr<Device3> m_Device3; // D3D11 Device
	Mutex m_Mtx; // Lock 

internal:

	CoreRenderer3();

	// Creates renderer device and context. Throws on failure. 
	Void Create( 
		_Inout_opt_ D3D_FEATURE_LEVEL *pFeatureLevel = null,					// Resulting hardware feature level. 
		_In_opt_ D3D_DRIVER_TYPE eDriverType = D3D_DRIVER_TYPE_HARDWARE		// Hardware driver type (use reference type for debugging). 
		);

	// Creates the deferred context and stores pointer to the provided reference. Throws on failure. 
	_Outptr_ DeferredContext3Ptr CreateDeferredContext(
		_Inout_ WRL::ComPtr<DeferredContext3> &pDeferredContext
		);

	// Present context to front buffer 
	HERZELEID_FORCEINLINING HERZELEID_NOALIAS Void Present( 
		_In_ SwapChainPtr pSwapchain, // Swapchain pointer
		_In_ Bool bVsync, // Enable vertical sync 
		_In_ DXGI_PRESENT_PARAMETERS *pParams, // dirty/scroll rects 
		_In_ UInt32 uiFlags = NoFlags // extra flags
		)
	{
		pSwapchain->Present1( bVsync, uiFlags, pParams );
	}

	// Present context to front buffer 
	HERZELEID_FORCEINLINING HERZELEID_NOALIAS Void Present( 
		_In_ SwapChainPtr pSwapchain, // Swapchain pointer
		_In_ Bool bVsync, // Enable vertical sync 
		_In_ UInt32 uiFlags = NoFlags // extra flags
		)
	{
		DXGI_PRESENT_PARAMETERS Params;
		Standard::ZeroValue(&Params);
		pSwapchain->Present1( bVsync, uiFlags, &Params );
	}

} HerzeleidRendererCoreNamespaceEnd; 

 #ifdef HERZELEID_DESKTOP
  #undef internal
  #undef ref
 #else
 #endif // HERZELEID_DESKTOP

 #endif // HERZELEID_CORERENDERER3_INCLUDED__
